package club.vann.kafka.mock.common.model.mapper;

import club.vann.kafka.mock.common.model.info.FrontEndTable;
import club.vann.kafka.mock.common.model.info.FrontEndTableDataSchema;
import com.cyberx.lunyu.TableDataOuterClass;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
import org.springframework.util.ObjectUtils;

/** 用于 Table 相关实体转换。 */
@Mapper(
    componentModel = "spring",
    collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
    nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
    nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface FrontEndTableMapper {
  FrontEndTableMapper INSTANCE = Mappers.getMapper(FrontEndTableMapper.class);

  List<FrontEndTable.Column> convert(List<FrontEndTableDataSchema.Column> columns);

  @Mapping(source = "columnList", target = "columns")
  FrontEndTable convert(TableDataOuterClass.TableData tableData);

  static List<FrontEndTable.Row> rowListToRowArray(
      List<TableDataOuterClass.Column> columnList, List<TableDataOuterClass.Row> rowList) {
    if (ObjectUtils.isEmpty(rowList)) {
      return Collections.emptyList();
    }
    List<FrontEndTable.Row> rows = new ArrayList<>();
    rowList.forEach(
        row -> {
          FrontEndTable.Row r = rowToRow(columnList, row);
          if (r != null) {
            rows.add(r);
          }
        });
    return rows;
  }

  static FrontEndTable.Row rowToRow(
      List<TableDataOuterClass.Column> columnList, TableDataOuterClass.Row row) {
    List<TableDataOuterClass.Cell> cellList = row.getCellList();
    if (ObjectUtils.isEmpty(row) || ObjectUtils.isEmpty(row.getCellList())) {
      return null;
    }
    return new FrontEndTable.Row(rowList(columnList, cellList));
  }

  static Object[] rowList(
      List<TableDataOuterClass.Column> columnList, List<TableDataOuterClass.Cell> cellList) {
    Object[] data = new Object[columnList.size()];
    for (int i = 0; i < cellList.size(); i++) {
      data[i] = cellValue(columnList.get(i), cellList.get(i));
    }
    return data;
  }

  static Object cellValue(TableDataOuterClass.Column column, TableDataOuterClass.Cell cell) {
    Object value = null;
    String columnDataType = column.getDataType();
    if (FrontEndTable.DataType.DOUBLE.name().equals(columnDataType)) {
      value = cell.getDoubleData();
    } else if (FrontEndTable.DataType.STRING.name().equals(columnDataType)) {
      value = cell.getStringData();
    } else if (FrontEndTable.DataType.TIMESTAMP.name().equals(columnDataType)) {
      value = cell.getLongData();
    }
    return value;
  }
}
